//
//  YLEmptyDataImplement.swift
//  Swift-Codedase
//
//  Created by xyanl on 2023/9/12.
//


import Foundation
import UIKit

/// TableView/CollectionView 对象的委托必须采用 YLEmptyDataImplementDelegate 协议。协议的方法允许委托执行占位符操作。
@objc protocol YLEmptyDataImplementDelegate {
    
    /// 实现这个方法，添加默认占位符提供者，新的占位符cell
    @objc func customEmptyDataProvider(_ view: Any)
    
    /// 当没有数据的时候展示该占位符
    @objc optional func showEmptyDataForNoData(in view: Any)
    
    /// 点击占位符上按钮
    /// - Parameters:
    ///   - view: UITableView or UICollectionView
    ///   - key: YLEmptyDataKey 的 key，根据key判断是哪个paceholder view
    @objc optional func emptyData(_ view: Any, clickPlaceholderButton key: String)
    
}

/// 这个类负责实现UITableView和UITableView的DataSource和Delegate协议。
/// 每个占位符视图都是一个tableview，只有一个单元格，它占用了整个tableview框架
class YLEmptyDataImplement: NSObject {
    
    let object: YLEmptyDataObject
    
    init(_ object: YLEmptyDataObject) {
        self.object = object
    }
    
    /// 通过移除顶部和底部插入项、刷新控件的高度，返回滚动视图的高度
    /// - Parameter scrollView: the scroll view
    /// - Returns: 通过移除顶部和底部插入项、刷新控件的高度，返回滚动视图的高度
    func height(of scrollView: UIScrollView) -> CGFloat {
        var height = scrollView.bounds.height
        if #available(iOS 10, *) {
            height -= scrollView.refreshControl?.bounds.height ?? 0
        }
        if #available(iOS 11, *) {
            height -= (scrollView.adjustedContentInset.top + scrollView.adjustedContentInset.bottom)
        } else {
            height -= (scrollView.contentInset.top + scrollView.contentInset.bottom)
        }
        return height
    }
    
}

// MARK: - UITableViewDelegate

// 占位符模板数据源，采用UITableViewDataSource协议
extension YLEmptyDataImplement: UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 1 }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let identifier = object.cellIdentifier
        guard let cell = tableView.dequeueReusableCell(withIdentifier: identifier) else {
            fatalError("请检查 cellIdentifier：\(identifier) 是否被注册")
        }
        cell.selectionStyle = .none

        guard let aCell = cell as? YLEmptyDataTableViewCell else {
            return cell
        }
        aCell.data = object.data
        
        // 将操作转发给占位符委托
        aCell.onActionButtonTap = { [unowned self] in
            guard let placeholderTableView = (tableView as? YLEmptyDataTableView) else { return }
            if let _ = placeholderTableView.emptyDataDelegate?.emptyData {
                placeholderTableView.emptyDataDelegate?.emptyData!(tableView, clickPlaceholderButton: object.data.key.key)
            }
        }
        
        return cell
    }
}

/**
 占位符模板委托，采用UITableViewDelegate协议
 实现方法'tableView:heightForRowAt:'将单元格大小改为tableView大小
 tableView:willDisplay:在需要的时候动画单元格
 */
extension YLEmptyDataImplement: UITableViewDelegate {
    
    // 占位符单元格始终采用tableView的大小
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        
        var tableViewHeight = height(of: tableView)
        
        // 减去tableHeaderView的高度
        if object.shouldShowTableViewHeader != true {
            tableViewHeight -= tableView.tableHeaderView?.bounds.height ?? 0
        }
        
        // 减去tableFooterView的高度
        if object.shouldShowTableViewFooter != true {
            tableViewHeight -= tableView.tableFooterView?.bounds.height ?? 0
        }
        
        return tableViewHeight
    }
}


// MARK: - UICollectionView

extension YLEmptyDataImplement: UICollectionViewDataSource {
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 1 }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let reuseIdentifier = object.cellIdentifier 
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath)
        
        guard let aCell = cell as? YLEmptyDataCollectionViewCell else {
            return cell
        }
        
        aCell.data = object.data
        
        // forward action to placeholder delegate
        aCell.onActionButtonTap = { [unowned self] in
            guard let aCollectionView = collectionView as? YLEmptyDataCollectionView else { return }
            aCollectionView.emptyDataDelegate?.emptyData!(collectionView, clickPlaceholderButton: object.data.key.key)
        }
        return cell
    }
}

extension YLEmptyDataImplement: UICollectionViewDelegateFlowLayout {
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        .zero
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
        .zero
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        
        let collectionViewHeight = height(of: collectionView)
        return CGSize(width: collectionView.bounds.width, height: collectionViewHeight)
    }
}

